#define _CRT_SECURE_NO_WARNINGS 

#include"string.h"

namespace xyc
{
	string::string(const char* str)
	{
		size_t sz = strlen(str);
		_str=new char[sz + 1];
		_size = sz;
		_capacity = sz;
		strcpy(_str, str);
	}

	string::~string()
	{
		delete[] _str;
		_str = nullptr;
	}

	const char* string::c_str() const
	{
		return _str;
	}

	char& string::operator[](size_t i)
	{
		assert(i < _size);
		return _str[i];
	}
	const char& string::operator[](size_t i) const
	{
		assert(i < _size);
		return _str[i];
	}
	size_t string::size() const
	{
		return _size;
	}

	string::iterator string::begin()
	{
		return _str;
	}
	string::iterator string:: end()
	{
		return _str + _size;
	}
	string::iterator string::begin() const
	{
		return _str;
	}
	string::iterator string::end() const
	{
		return _str + _size;
	}

	void string::reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* newstr = new char[n + 1];
			strcpy(newstr, _str);
			delete[] _str;
			_str = newstr;
			_capacity = n;
		}
	}

	void string:: push_back(char ch)
	{
		if (_size >= _capacity)
		{
			size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(newcapacity);
		}

		_str[_size] = ch;
		++_size;
		_str[_size] = '\0';
	}
	void string:: append(const char* str)
	{
		size_t len = strlen(str);
		if (_size + len >= _capacity)
		{
			size_t newcapacity = 2 * _capacity > _size + len  ?  2 * _capacity: _size + len;
			reserve(newcapacity);
		}
		strcpy(_str + _size, str);
		_size += len;
	}
	string& string::operator+=(char ch)
	{
		push_back(ch);
		return *this;
	}
	string& string::operator+=(const char* str)
	{
		size_t len = strlen(str);
		append(str);
		return *this;
	}
	ostream& operator<<(ostream& out, string& s)
	{
		for (size_t i = 0;i<s.size();i++)
		{
			out << s[i];
		}

		return out;
	}
}
